package com.mx.ymate.modbus.impl;

import com.digitalpetri.modbus.requests.ReadHoldingRegistersRequest;
import com.digitalpetri.modbus.requests.WriteMultipleRegistersRequest;
import com.digitalpetri.modbus.requests.WriteSingleRegisterRequest;
import com.digitalpetri.modbus.responses.ReadHoldingRegistersResponse;
import com.digitalpetri.modbus.responses.WriteMultipleRegistersResponse;
import com.digitalpetri.modbus.responses.WriteSingleRegisterResponse;
import com.digitalpetri.modbus.slave.ServiceRequestHandler;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.ReferenceCountUtil;

/**
 * @Author: mengxiang.
 * @Date 2025/11/10.
 * @Time: 16:00.
 * @Description: 默认实现，基于 Map<Integer,Integer> 作为寄存器缓存
 */
public class DefaultServiceRequestHandler implements ServiceRequestHandler {

    /**
     * 读取保持寄存器
     *
     * @param service
     */
    @Override
    public void onReadHoldingRegisters(ServiceRequest<ReadHoldingRegistersRequest, ReadHoldingRegistersResponse> service) {
        ReadHoldingRegistersRequest request = service.getRequest();
        int address = request.getAddress();
        int quantity = request.getQuantity();

        ByteBuf buf = Unpooled.buffer(quantity * 2);
        for (int i = 0; i < quantity; i++) {
            buf.writeShort(ModbusCache.read(address + i));
        }

        service.sendResponse(new ReadHoldingRegistersResponse(buf));
        buf.release();
        ReferenceCountUtil.release(request);
    }

    /**
     * 写单个保持寄存器
     *
     * @param service
     */
    @Override
    public void onWriteSingleRegister(ServiceRequest<WriteSingleRegisterRequest, WriteSingleRegisterResponse> service) {
        WriteSingleRegisterRequest request = service.getRequest();
        int address = request.getAddress();
        int value = request.getValue();

        ModbusCache.write(address, value);
        service.sendResponse(new WriteSingleRegisterResponse(address, value));
        ReferenceCountUtil.release(request);
    }

    /**
     * 写多个保持寄存器
     *
     * @param service
     */
    @Override
    public void onWriteMultipleRegisters(ServiceRequest<WriteMultipleRegistersRequest, WriteMultipleRegistersResponse> service) {
        WriteMultipleRegistersRequest request = service.getRequest();
        int address = request.getAddress();
        int quantity = request.getQuantity();
        ByteBuf values = request.getValues();

        ModbusCache.write(address, values);
        service.sendResponse(new WriteMultipleRegistersResponse(address, quantity));
        ReferenceCountUtil.release(request);
    }

}
